package com.olap.starter.common.service.crud.impl.builder;

import com.olap.starter.common.vo.ExecuteQuery;
import com.olap.starter.common.vo.QueryData;
import lombok.extern.log4j.Log4j2;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.olap.starter.common.util.QueryGeneratorUtil.getSqlAndParams;
import static com.olap.starter.common.util.QueryGeneratorUtil.replacePlaceholdersWithQuestionMarks;

@Log4j2
@Component
public class CRUDExecuteBuilder {

    ExecutorService executor = Executors.newFixedThreadPool(4);

    public QueryData doQueryData(JdbcTemplate jdbcTemplate, ExecuteQuery executeQuery) {
        String exSql = replacePlaceholdersWithQuestionMarks(executeQuery.getExSql());
        String exSqlc = replacePlaceholdersWithQuestionMarks(executeQuery.getExCountSql());
        Object[] sqlAndParams = getSqlAndParams(executeQuery);
        log.info("==>  listSQL:\n" + executeQuery.getExSqlStr());
        CompletableFuture<List<Map<String, Object>>> list = CompletableFuture.supplyAsync(() -> jdbcTemplate.queryForList(exSql, sqlAndParams), executor);
        CompletableFuture<Map<String, Object>> map = CompletableFuture.supplyAsync(() -> jdbcTemplate.queryForMap(exSqlc, sqlAndParams), executor);
        CompletableFuture.allOf(list, map).join();
        try {
            return new QueryData(list.get(), map.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public List<Map<String, Object>> queryFlux(JdbcTemplate jdbcTemplate, ExecuteQuery executeQuery) {
        String exSql = replacePlaceholdersWithQuestionMarks(executeQuery.getExSql());
        Object[] sqlAndParams = getSqlAndParams(executeQuery);
        log.info("==>  listSQL:\n" + executeQuery.getExSqlStr());
        return jdbcTemplate.queryForList(exSql, sqlAndParams);
    }
}
